package com.example.service.webhook.business.carrier.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.example.service.webhook.business.carrier.dto.*;
import com.example.service.webhook.business.carrier.dto.union.*;
import com.example.service.webhook.business.carrier.entity.*;
import com.example.service.webhook.business.carrier.repository.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import com.example.service.webhook.business.carrier.api.CarrierClient;
import com.example.service.webhook.business.carrier.billitem.CarrierBillTask;
import com.example.service.webhook.util.DateUtil;

/**
 * 运营商处理类
 * 手机号是基本单位
 * 1、基本信息
 * 2、套餐记录
 * 3、账单记录
 * 4、通话详情
 * 5、短信详情
 * 6、充值记录
 * 7、亲情网记录
 * ClassName: CarrierBillService
 * date: 2016年7月20日 下午5:35:35
 *
 * @author yuandong
 * @since JDK 1.6
 */
@Service
public class CarrierBillService {
    private static final Logger LOGGER = LoggerFactory.getLogger(CarrierBillService.class);

    @Autowired
    private CarrierClient carrierClient;

    @Autowired
    private MobileBasicRepository mobileBasicRepository;

    @Autowired
    private PackageUsageRepository packageUsageRepository;

    @Autowired
    private MobileBillRepository mobileBillRepository;

    @Autowired
    private MobileVoiceCallRepository mobileVoiceCallRepository;

    @Autowired
    private MobileSmsRepository mobileSmsRepository;

    @Autowired
    private MobileNetRepository mobileNetRepository;

    @Autowired
    private MobileRechargeRepository mobileRechargeRepository;
    @Autowired
    private FamilyMemberRepository familyMemberRepository;

    @Autowired
    private MonthInfoRepository monthInfoRepository;

    @Autowired
    private MonthInfoItemRepository monthInfoItemRepository;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    public void fetchBill(final CarrierBillTask task) {
        // 这里交给线程池处理，防止下面的业务处理时间太长，导致超时。
        // 超时会导致魔蝎数据进行重试，会收到重复的回调请求
        taskExecutor.execute(
                new Runnable() {
                    @Override
                    public void run() {

                        try {
//							MobileBasic mobilebasic = carrierClient.getMobileBasic(task.getMobile(),task.getTaskId());
                                UnionDataV3 mxData = carrierClient.getMxData(task.getMobile(), task.getTaskId());
                            if (mxData != null) {
                                LOGGER.info("开始-处理用户数据: {}", task.getTaskId());
                                //1、处理基本信息
                                saveMobileBasic(task, mxData);
                                //后面的查询最近6个月的数据,这里根据自己的业务来
                                String fromMonth = DateUtil.getStrFromDate(DateUtil.addMonth(DateUtil.getCurrentDate(), -6), "yyyy-MM");
                                String toMonth = DateUtil.getStrFromDate(DateUtil.getCurrentDate(), "yyyy-MM");
                                //2、套餐记录(一般情况下，第一次爬取只会有当月的套餐。如果历史爬取过，会有历史的)
                                savePackageUsage(task, mxData.getPackages());

                                //6、充值记录
                                saveRecharge(task, mxData.getRecharges());
                                //7、亲情网
                                saveFamily(task, mxData.getFamilies());
                                //3、账单记录
                                saveBill(task, mxData.getBills());
                                //4、通话详情
                                saveCall(task, mxData.getCalls());
                                //5、短信详情
                                saveSms(task, mxData.getSmses());

//                                saveNet(task, mxData.getNets());

                                //保存语音月份信息
                                saveMonth(task,mxData.getMonthInfo());

                                LOGGER.info("结束-处理用户数据: {}", task.getTaskId());
                            }

                            //下面的接口采用的v2，按照单个月来查询数据
//            				if(task.getBills()!=null&&!task.getBills().isEmpty()){
//            					for(String month:task.getBills()){
//            						//4、通话详情
//            						saveCall(task,month);
//            						//5、短信详情
//            						saveSms(task,month);
//
//            					}
//            				}


                        } catch (Exception e) {
                            LOGGER.error("fetchBill failed. task:{}", task.getTaskId(), e);
                        }

                    }
                }


        );
    }

    private void saveMonth(CarrierBillTask task,UnionMonthInfo monthInfo){
        if (null != monthInfo){
            MonthInfoEntity monthInfoEntity = new MonthInfoEntity();
            BeanUtils.copyProperties(monthInfo,monthInfoEntity);
            monthInfoEntity.setUserId(task.getUserId());
            //先删除
            monthInfoRepository.deleteMonthInfo(task.getUserId(),monthInfo.getMobile());
            try {
                monthInfoRepository.saveMobileMonthInfo(monthInfoEntity);
            } catch (Exception e) {
                LOGGER.error("saveBill failed. taskId:{}", task.getTaskId(), e);
            }

            for(String key : monthInfo.getMonthList().keySet()){
                MonthItemEntity itemEntity = new MonthItemEntity();
                itemEntity.setUserId(task.getUserId());
                itemEntity.setMobile(task.getMobile());

                itemEntity.setMonth(key);
                itemEntity.setValue(monthInfo.getMonthList().get(key));
                try {
                    monthInfoItemRepository.saveMonthItemEntity(itemEntity);
                } catch (Exception e) {
                    LOGGER.error("saveBill failed. taskId:{}", task.getTaskId(), e);
                }
            }
        }
    }

    private void saveMobileBasic(CarrierBillTask task, UnionDataV3 mxData) {
        try {
            MobileBasicEntity mobileBasicEntity = loadMobileBasicByCallApi(task.getUserId(), mxData);
            MobileBasicEntity isExist = mobileBasicRepository.getMobileBasic(task.getUserId(), task.getMobile());
            if (isExist != null) {
                mobileBasicEntity.setId(isExist.getId());
                mobileBasicEntity.setCreateTime(isExist.getCreateTime());

                mobileBasicRepository.updateMobileBasic(mobileBasicEntity);
            } else {
                mobileBasicRepository.saveMobileBasic(mobileBasicEntity);
            }
        } catch (Exception e) {
            LOGGER.error("saveMobileBasic error,task:{}", task.getTaskId(), e);
        }
    }


    private MobileBasicEntity loadMobileBasicByCallApi(String userId, UnionDataV3 mxData) throws IOException {
        if (mxData != null) {
            MobileBasicEntity basicEntity = new MobileBasicEntity();
            BeanUtils.copyProperties(mxData, basicEntity);
            basicEntity.setUserId(userId);
            if (mxData.getOpenTime() != null) {
                basicEntity.setOpenTime(DateUtil.getDateFromString(mxData.getOpenTime(), "yyyy-MM-dd"));
            }
            return basicEntity;
        }
        return null;
    }


    private void savePackageUsage(CarrierBillTask task, List<UnionPackageUsage> packageUsages) {
        try {

            if (packageUsages != null && !packageUsages.isEmpty()) {
                //删除这个月的此用户此手机号的套餐信息
                packageUsageRepository.deletePackageUsage(task.getUserId(), task.getMobile());
                List<PackageUsageEntity> packageuseList = new ArrayList<>();
                for (UnionPackageUsage packageUsage : packageUsages) {
                    if (packageUsage.getItems() != null && !packageUsage.getItems().isEmpty()) {

                        //新增这个月的套餐信息
                        PackageUsageEntity packageUsageEntity = new PackageUsageEntity();
                        for (PackageItem packageItem : packageUsage.getItems()) {
                            BeanUtils.copyProperties(packageItem, packageUsageEntity);
                            packageUsageEntity.setMobile(task.getMobile());
                            packageUsageEntity.setUserId(task.getUserId());
//							packageUsageEntity.setBillMonth(packageUsage.getBillMonth());
                            packageUsageEntity.setBillStartDate(packageUsage.getBillStartDate());
                            packageUsageEntity.setBillEndDate(packageUsage.getBillEndDate());
//							packageUsageRepository.save(packageUsageEntity);
//                            packageUsageRepository.savePackageUsage(packageUsageEntity);
                            packageuseList.add(packageUsageEntity);
                        }
                    }
                }
                packageUsageRepository.batchSave(packageuseList);
            }

        } catch (Exception e) {
            LOGGER.error("savePackageUsage failed. taskId:{}", task.getTaskId(), e);
        }

    }


    private void saveBill(CarrierBillTask task, List<UnionBill> bills) {
        try {
            if (bills != null && !bills.isEmpty()) {
                for (UnionBill mobileBill : bills) {
                    MobileBillEntity mobileBillEntity = new MobileBillEntity();
                    BeanUtils.copyProperties(mobileBill, mobileBillEntity);
                    mobileBillEntity.setUserId(task.getUserId());
                    mobileBillEntity.setMobile(task.getMobile());

                    //userId+mobile+billMonth做为唯一约束
                    MobileBillEntity isExist = mobileBillRepository.getMobileBill(task.getUserId(), task.getMobile(), mobileBill.getBillMonth());
                    if (isExist != null) {
                        mobileBillEntity.setId(isExist.getId());
                        mobileBillEntity.setCreateTime(isExist.getCreateTime());
                        mobileBillRepository.updateMobileBill(mobileBillEntity);
                    } else {
                        mobileBillRepository.saveMobileBill(mobileBillEntity);
                    }
                }

            }
        } catch (Exception e) {
            LOGGER.error("saveBill failed. taskId:{}", task.getTaskId(), e);
        }

    }


    private void saveCall(CarrierBillTask task, List<UnionVoiceCall> calls) {
        try {

            if (calls != null && !calls.isEmpty()) {
            	List<MobileVoiceCallEntity> mobileVoiceCalls = new ArrayList<>();
                for (UnionVoiceCall mobileVoiceCallDetail : calls) {
                    if (mobileVoiceCallDetail != null && !mobileVoiceCallDetail.getVoiceCallItems().isEmpty()) {
                        mobileVoiceCallRepository.deleteMobileVoiceCall(task.getUserId(), task.getMobile(), mobileVoiceCallDetail.getBillMonth());
                        for (UnionVoiceCallItem mobileVoiceCall : mobileVoiceCallDetail.getVoiceCallItems()) {
                            MobileVoiceCallEntity mobileVoiceCallEntity = new MobileVoiceCallEntity();
                            BeanUtils.copyProperties(mobileVoiceCall, mobileVoiceCallEntity);
                            mobileVoiceCallEntity.setUserId(task.getUserId());
                            mobileVoiceCallEntity.setMobile(task.getMobile());
                            mobileVoiceCallEntity.setBillMonth(mobileVoiceCallDetail.getBillMonth());
//                            mobileVoiceCallRepository.saveMobileVoiceCall(mobileVoiceCallEntity);
                            mobileVoiceCalls.add(mobileVoiceCallEntity);
                        }
                        
                    }

                }
                mobileVoiceCallRepository.batchSave(task.getUserId(), mobileVoiceCalls);
            }

        } catch (Exception e) {
            LOGGER.error("saveCall failed. taskId:{}", task.getTaskId(), e);
        }
    }


    private void saveSms(CarrierBillTask task, List<UnionShortMessage> shortMessages) {
        try {
            if (shortMessages != null && !shortMessages.isEmpty()) {
            	List<MobileSmsEntity> smsList = new ArrayList<>();
                for (UnionShortMessage mobileSmsDetail : shortMessages) {
                    if (mobileSmsDetail != null && !mobileSmsDetail.getShortMessageItems().isEmpty()) {

                        mobileSmsRepository.deleteMobileSms(task.getUserId(), task.getMobile(), mobileSmsDetail.getBillMonth());

                        for (UnionShortMessageItem mobileSms : mobileSmsDetail.getShortMessageItems()) {
                            MobileSmsEntity mobileSmsEntity = new MobileSmsEntity();
                            BeanUtils.copyProperties(mobileSms, mobileSmsEntity);
                            mobileSmsEntity.setUserId(task.getUserId());
                            mobileSmsEntity.setMobile(task.getMobile());
                            mobileSmsEntity.setBillMonth(mobileSmsDetail.getBillMonth());
//                            mobileSmsRepository.saveMobileSms(mobileSmsEntity);
                            smsList.add(mobileSmsEntity);
                        }
                    }

                }
                
                mobileSmsRepository.batchSave(task.getUserId(),smsList);

            }

        } catch (Exception e) {
            LOGGER.error("saveSms failed. taskId:{}", task.getTaskId(), e);
        }
    }

    private void saveNet(CarrierBillTask task, List<UnionNetFlow> nets) {
        try {
            if (nets != null && !nets.isEmpty()) {
                for (UnionNetFlow netFlow : nets) {
                    if (netFlow != null && !netFlow.getNetFlowItems().isEmpty()) {

                        mobileNetRepository.deleteMobileNetFlow(task.getUserId(), task.getMobile(), netFlow.getBillMonth());
                        List<NetFlowEntity> netflows = new ArrayList<>();
                        for (UnionNetFlowItem netFlowItem : netFlow.getNetFlowItems()) {
                            NetFlowEntity netFlowEntity = new NetFlowEntity();
                            BeanUtils.copyProperties(netFlowItem, netFlowEntity);
                            netFlowEntity.setUserId(task.getUserId());
                            netFlowEntity.setMobile(task.getMobile());
                            netFlowEntity.setBillMonth(netFlow.getBillMonth());
//                            mobileNetRepository.saveNetFlow(netFlowEntity);
                            netflows.add(netFlowEntity);
                        }
                        
                        mobileNetRepository.batchSave(task.getUserId(), netflows);
                    }

                }

            }

        } catch (Exception e) {
            LOGGER.error("saveNet failed. taskId:{}", task.getTaskId(), e);
        }
    }

    private void saveRecharge(CarrierBillTask task, List<UnionRecharge> mobileRecharges) {
        try {

            if (mobileRecharges != null && !mobileRecharges.isEmpty()) {
                mobileRechargeRepository.deleteMobileRecharge(task.getUserId(), task.getMobile());
                List<MobileRechargeEntity> rechargeList = new ArrayList<>();
                for (UnionRecharge mobileRecharge : mobileRecharges) {
                    if (mobileRecharge != null) {
                        MobileRechargeEntity mobileRechargeEntity = new MobileRechargeEntity();
                        BeanUtils.copyProperties(mobileRecharge, mobileRechargeEntity);
                        mobileRechargeEntity.setUserId(task.getUserId());
                        mobileRechargeEntity.setMobile(task.getMobile());
//				   	   mobileRechargeRepository.save(mobileRechargeEntity);
//                        mobileRechargeRepository.saveMobileRecharge(mobileRechargeEntity);
                        rechargeList.add(mobileRechargeEntity);
                    }
                }
                mobileRechargeRepository.batchSave(rechargeList);
            }


        } catch (Exception e) {
            LOGGER.error("saveRecharge failed. taskId:{}", task.getTaskId(), e);
        }
    }


    /**
     * saveFamily:保存和此手机号关联的亲情网号码 <br/>
     * TODO(这里描述这个方法适用条件 – 可选).<br/>
     * TODO(这里描述这个方法的执行流程 – 可选).<br/>
     * TODO(这里描述这个方法的使用方法 – 可选).<br/>
     * TODO(这里描述这个方法的注意事项 – 可选).<br/>
     *
     * @param task
     * @author yuandong
     * @since JDK 1.6
     */
    private void saveFamily(CarrierBillTask task, List<UnionFamilyNet> familyNets) {
        try {
            if (familyNets != null && !familyNets.isEmpty()) {

                for (UnionFamilyNet familyNet : familyNets) {
                    if (familyNet.getFamilyMembers() != null && !familyNet.getFamilyMembers().isEmpty()) {
                        //删除这一组亲情网
                        familyMemberRepository.deleteFamilyMember(task.getUserId(), task.getMobile(), familyNet.getFamilyNetNum());
                        //添加亲情网
                        for (FamilyMember familyMember : familyNet.getFamilyMembers()) {
                            if (familyMember.getLongNumber() != null && familyMember.getShortNumber() != null && familyMember.getMemberType() != null) {
                                FamilyMemberEntity familyMemberEntity = new FamilyMemberEntity();
                                BeanUtils.copyProperties(familyMember, familyMemberEntity);
                                familyMemberEntity.setUserId(task.getUserId());
                                familyMemberEntity.setMobile(task.getMobile());
                                familyMemberEntity.setFamilyNetNum(familyNet.getFamilyNetNum());
                                familyMemberRepository.saveFamilyMember(familyMemberEntity);
                            }

                        }
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("saveRecharge failed. taskId:{}", task.getTaskId(), e);
        }
    }


}
